using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Threading;
using System.Windows.Forms;

namespace HslControls
{
	/// <summary>
	/// 进度条控件，支持横向和纵向的两种模式，支持动画效果
	/// </summary>
	[Description("进度条控件，支持横向，竖向，圆形三种样式")]
	public class HslProgress : UserControl
	{
		private StringFormat sf = null;

		private Brush backBrush = new SolidBrush(Color.DimGray);

		private Color progressColor = Color.Tomato;

		private Brush progressBrush = new SolidBrush(Color.Tomato);

		private Color borderColor = Color.DimGray;

		private Pen borderPen = new Pen(Color.DimGray, 1f);

		private int max = 100;

		private int m_value = 50;

		private int m_actual = 50;

		private int m_speed = 1;

		private bool useAnimation = false;

		private int m_version = 0;

		private HslProgressStyle m_progressStyle = HslProgressStyle.Vertical;

		private bool isTextRender = true;

		private string textRenderFormat = string.Empty;

		private Action m_UpdateAction;

		/// <summary> 
		/// 必需的设计器变量。
		/// </summary>
		private IContainer components = null;

		/// <summary>
		/// 获取或设置进度条的背景色
		/// </summary>
		[Description("获取或设置进度条的背景色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "DimGray")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		[Browsable(true)]
		public override Color BackColor
		{
			get
			{
				return base.BackColor;
			}
			set
			{
				base.BackColor = value;
				backBrush?.Dispose();
				backBrush = new SolidBrush(value);
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置进度的颜色
		/// </summary>
		[Description("获取或设置进度条的前景色")]
		[Category("HslControls")]
		[Browsable(true)]
		[DefaultValue(typeof(Color), "Tomato")]
		public Color ProgressColor
		{
			get
			{
				return progressColor;
			}
			set
			{
				progressColor = value;
				progressBrush?.Dispose();
				progressBrush = new SolidBrush(value);
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置进度条的最大值，默认为100
		/// </summary>
		[Description("获取或设置进度条的最大值，默认为100")]
		[Category("HslControls")]
		[Browsable(true)]
		[DefaultValue(100)]
		public int Max
		{
			get
			{
				return max;
			}
			set
			{
				if (value > 1)
				{
					max = value;
				}
				if (m_value > max)
				{
					m_value = max;
				}
				Invalidate();
			}
		}

		/// <summary>
		/// 当前进度条的值，不能大于最大值或小于0
		/// </summary>
		[Description("获取或设置当前进度条的值")]
		[Category("HslControls")]
		[Browsable(true)]
		[DefaultValue(50)]
		public int Value
		{
			get
			{
				return m_value;
			}
			set
			{
				if (value >= 0 && value <= max && value != m_value)
				{
					m_value = value;
					if (UseAnimation)
					{
						int version = Interlocked.Increment(ref m_version);
						ThreadPool.QueueUserWorkItem(ThreadPoolUpdateProgress, version);
					}
					else
					{
						m_actual = value;
						Invalidate();
					}
				}
			}
		}

		/// <summary>
		/// 是否显示进度
		/// </summary>
		[Description("获取或设置是否显示进度文本")]
		[Category("HslControls")]
		[Browsable(true)]
		[DefaultValue(true)]
		public bool IsTextRender
		{
			get
			{
				return isTextRender;
			}
			set
			{
				isTextRender = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 设置进度条的边框颜色
		/// </summary>
		[Description("获取或设置进度条的边框颜色")]
		[Category("HslControls")]
		[Browsable(true)]
		[DefaultValue(typeof(Color), "DimGray")]
		public Color BorderColor
		{
			get
			{
				return borderColor;
			}
			set
			{
				borderColor = value;
				borderPen?.Dispose();
				borderPen = new Pen(value);
				Invalidate();
			}
		}

		/// <summary>
		/// 设置进度变更的速度
		/// </summary>
		[Description("获取或设置进度条的变化进度")]
		[Category("HslControls")]
		[Browsable(true)]
		[DefaultValue(1)]
		public int ValueChangeSpeed
		{
			get
			{
				return m_speed;
			}
			set
			{
				if (value >= 1)
				{
					m_speed = value;
				}
			}
		}

		/// <summary>
		/// 获取或设置进度条变化的时候是否采用动画效果
		/// </summary>
		[Description("获取或设置进度条变化的时候是否采用动画效果")]
		[Category("HslControls")]
		[Browsable(true)]
		[DefaultValue(false)]
		public bool UseAnimation
		{
			get
			{
				return useAnimation;
			}
			set
			{
				useAnimation = value;
			}
		}

		/// <summary>
		/// 进度条的样式
		/// </summary>
		[Description("获取或设置进度条的样式")]
		[Category("HslControls")]
		[Browsable(true)]
		[DefaultValue(typeof(HslProgressStyle), "Vertical")]
		public HslProgressStyle ProgressStyle
		{
			get
			{
				return m_progressStyle;
			}
			set
			{
				m_progressStyle = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置自定义的格式化文本信息
		/// </summary>
		[Description("获取或设置自定义的格式化文本信息")]
		[Category("HslControls")]
		[Browsable(true)]
		[DefaultValue("")]
		public string TextRenderFormat
		{
			get
			{
				return textRenderFormat;
			}
			set
			{
				textRenderFormat = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 实例化一个对象
		/// </summary>
		public HslProgress()
		{
			InitializeComponent();
			sf = new StringFormat();
			sf.Alignment = StringAlignment.Center;
			sf.LineAlignment = StringAlignment.Center;
			SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, value: true);
			SetStyle(ControlStyles.ResizeRedraw, value: true);
			SetStyle(ControlStyles.OptimizedDoubleBuffer, value: true);
			SetStyle(ControlStyles.AllPaintingInWmPaint, value: true);
			m_UpdateAction = UpdateRender;
		}

		/// <summary>
		/// 重绘整个控件的界面
		/// </summary>
		/// <param name="e">重绘事件</param>
		protected override void OnPaint(PaintEventArgs e)
		{
			PaintHslControls(e.Graphics, base.Width, base.Height);
			base.OnPaint(e);
		}

		/// <inheritdoc cref="M:HslControls.HslArrow.PaintHslControls(System.Drawing.Graphics,System.Single,System.Single)" />
		public void PaintHslControls(Graphics g, int width, int height)
		{
			if (!Authorization.iashdiadasbdnajsdhjaf())
			{
				return;
			}
			try
			{
				g.FillRectangle(rect: new Rectangle(0, 0, width - 1, height - 1), brush: backBrush);
				g.SmoothingMode = SmoothingMode.HighQuality;
				g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
				switch (m_progressStyle)
				{
				case HslProgressStyle.Vertical:
				{
					int paintHeight = (int)((long)m_actual * (long)(height - 2) / max);
					g.FillRectangle(rect: new Rectangle(0, height - 1 - paintHeight, width - 1, paintHeight), brush: progressBrush);
					break;
				}
				case HslProgressStyle.Horizontal:
				{
					int paintWidth = (int)((long)m_actual * (long)(width - 2) / max);
					g.FillRectangle(rect: new Rectangle(0, 0, paintWidth + 1, height - 1), brush: progressBrush);
					break;
				}
				}
				Rectangle rectangle = new Rectangle(0, 0, width - 1, height - 1);
				if (isTextRender)
				{
					string str = string.IsNullOrEmpty(textRenderFormat) ? ((long)m_actual * 100L / max + "%") : string.Format(textRenderFormat, Value, Max);
					using Brush brush = new SolidBrush(ForeColor);
					if (m_progressStyle != HslProgressStyle.Circular)
					{
						g.DrawString(str, Font, brush, rectangle, sf);
					}
					else
					{
						g.DrawString("Not supported", Font, brush, rectangle, sf);
					}
				}
				if (m_progressStyle != HslProgressStyle.Circular)
				{
					g.DrawRectangle(borderPen, rectangle);
				}
			}
			catch (Exception)
			{
			}
		}

		private void ThreadPoolUpdateProgress(object obj)
		{
			try
			{
				int version = (int)obj;
				if (m_speed < 1)
				{
					m_speed = 1;
				}
				while (m_actual != m_value)
				{
					Thread.Sleep(17);
					if (version != m_version)
					{
						break;
					}
					int newActual = 0;
					if (m_actual > m_value)
					{
						int offect2 = m_actual - m_value;
						if (offect2 > m_speed)
						{
							offect2 = m_speed;
						}
						newActual = m_actual - offect2;
					}
					else
					{
						int offect = m_value - m_actual;
						if (offect > m_speed)
						{
							offect = m_speed;
						}
						newActual = m_actual + offect;
					}
					m_actual = newActual;
					if (version == m_version)
					{
						if (base.IsHandleCreated)
						{
							Invoke(m_UpdateAction);
						}
						continue;
					}
					break;
				}
			}
			catch (Exception)
			{
			}
		}

		private void UpdateRender()
		{
			Invalidate();
		}

		/// <summary> 
		/// 清理所有正在使用的资源。
		/// </summary>
		/// <param name="disposing">如果应释放托管资源，为 true；否则为 false。</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		/// <summary> 
		/// 设计器支持所需的方法 - 不要修改
		/// 使用代码编辑器修改此方法的内容。
		/// </summary>
		private void InitializeComponent()
		{
			SuspendLayout();
			base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
			BackColor = System.Drawing.Color.DimGray;
			base.Name = "HslProgress";
			base.Size = new System.Drawing.Size(120, 97);
			ResumeLayout(false);
		}
	}
}
